package com.slipper.listener;

import com.github.pagehelper.PageInfo;
import com.slipper.common.bo.UserDetail;
import com.slipper.constants.Constants;
import com.slipper.system.employee.bo.EmployeeBO;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class SessionListener implements HttpSessionListener {
    private Date startTime = new Date();
    private final Map<String, HttpSession> sessionMap = new ConcurrentHashMap<>();

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        if (session != null) {
            sessionMap.put(session.getId(), session);
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        if (session != null) {
            sessionMap.remove(session.getId());
        }
    }

    public PageInfo<EmployeeBO> onlineList(EmployeeBO bo) {
        List<EmployeeBO> employeeList = new ArrayList<>();
        sessionMap.values().forEach(session -> {
            UserDetail userDetail = Constants.getSessionUser(session);
            if (userDetail != null) {
                userDetail.getEmployee().setSessionId(session.getId());
                employeeList.add(userDetail.getEmployee());
            }
        });

        List<EmployeeBO> resultList = Collections.emptyList();
        int start = (bo.getPageNumber() - 1) * bo.getPageSize();
        int end = bo.getPageNumber() * bo.getPageSize();
        if (employeeList.size() >= end) {
            resultList = employeeList.subList(start, end);
        } else if (employeeList.size() > start) {
            resultList = employeeList.subList(start, employeeList.size());
        }

        PageInfo<EmployeeBO> pageInfo = new PageInfo<>();
        pageInfo.setList(resultList);
        pageInfo.setPageNum(bo.getPageNumber());
        pageInfo.setPageSize(bo.getPageSize());
        pageInfo.setTotal(employeeList.size());
        return pageInfo;
    }

    public void forceOffline(String employeeId) {
        sessionMap.values().forEach(session -> {
            UserDetail userDetail = Constants.getSessionUser(session);
            if (userDetail != null && userDetail.getEmployeeId().equals(employeeId)) {
                session.invalidate();
            }
        });
    }

    public long getSessionCount() {
        return sessionMap.values().stream().filter(session -> Constants.getSessionUser(session) != null).count();
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }
}
